﻿using CleanArchitecture.Core.Configuration;
using CleanArchitecture.Core.Handlers;
using CleanArchitecture.Core.Helper;
using CleanArchitecture.Infrastructure.Entities;
using CleanArchitecture.Infrastructure.Entities.Settings;
using CleanArchitecture.Infrastructure.Interfaces;
using CleanArchitecture.Infrastructure.Interfaces.Media;
using CleanArchitecture.Infrastructure.Models.Business.Columns;
using CleanArchitecture.Infrastructure.Models.Business.News;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CleanArchitecture.Web.FrontendUI
{
    public static class LayoutExtensions
    {
        private static ISettingService _settingService = EngineContext.Current.Resolve<ISettingService>();
        private static IWebHostEnvironment _hostingEnvironment = EngineContext.Current.Resolve<IWebHostEnvironment>();
        private static IActionContextAccessor _actionContextAccessor = EngineContext.Current.Resolve<IActionContextAccessor>();
        private static IUrlHelperFactory _urlHelperFactory = EngineContext.Current.Resolve<IUrlHelperFactory>();
        private static IFileUploadService _fileuploadService = EngineContext.Current.Resolve<IFileUploadService>();
        private static ClientSiteSettings GetClientSetting(EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC)
        {
            ClientSiteSettings clientSettingsModel;
            if (_settingService == null)
                _settingService = EngineContext.Current.Resolve<ISettingService>();
            switch (client)
            {
                case EntityEnumConfig.DataType.ClientMobile:
                    clientSettingsModel = _settingService.LoadSetting<ClientSiteMobileSettings>();
                    break;
                case EntityEnumConfig.DataType.ClientPC:
                default:
                    clientSettingsModel = _settingService.LoadSetting<ClientSitePCSettings>();
                    break;
            }
            return clientSettingsModel;
        }
        /// <summary>
        /// Generate all title parts
        /// </summary>
        /// <param name="html">HTML helper</param>
        /// <param name="addDefaultTitle">A value indicating whether to insert a default title</param>
        /// <param name="part">Title part</param>
        /// <returns>Generated string</returns>
        public static IHtmlContent NowaTitle(this IHtmlHelper html, EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC, ColumnItemModel currentColumn = null, NewsItemModel pageModel = null)
        {
            if (html == null) throw new ArgumentNullException(nameof(html));
            ClientSiteSettings clientSettingsModel = GetClientSetting(client);
            string pageTitle = clientSettingsModel.WebsiteName;
            if (currentColumn != null) pageTitle = currentColumn.Name + " - " + pageTitle;
            if (pageModel != null) pageTitle = pageModel.Title + " - " + pageTitle;
            return new HtmlString(html.Encode(pageTitle));
        }
        /// <summary>
        /// Generate all description parts
        /// </summary>
        /// <param name="html">HTML helper</param>
        /// <param name="part">Meta description part</param>
        /// <returns>Generated string</returns>
        public static IHtmlContent NowaMetaDescription(this IHtmlHelper html, EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC, ColumnItemModel currentColumn = null, NewsItemModel pageModel = null)
        {
            if (html == null) throw new ArgumentNullException(nameof(html));
            ClientSiteSettings clientSettingsModel = GetClientSetting(client);
            string pageDesc = clientSettingsModel.MetaDescription;
            if (currentColumn != null)
            {
                if (!string.IsNullOrEmpty(currentColumn.MetaDescription))
                    pageDesc = currentColumn.MetaDescription;
            }
            if (pageModel != null)
            {
                if (!string.IsNullOrEmpty(pageModel.MetaDescription))
                    pageDesc = pageModel.MetaDescription;
            }
            return new HtmlString(html.Encode(pageDesc));
        }
        /// <summary>
        /// Generate all keyword parts
        /// </summary>
        /// <param name="html">HTML helper</param>
        /// <param name="part">Meta keyword part</param>
        /// <returns>Generated string</returns>
        public static IHtmlContent NowaMetaKeywords(this IHtmlHelper html, EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC, ColumnItemModel currentColumn = null, NewsItemModel pageModel = null)
        {
            if (html == null) throw new ArgumentNullException(nameof(html));
            ClientSiteSettings clientSettingsModel = GetClientSetting(client);
            string pageKeyWords = clientSettingsModel.MetaKeywords;
            if (currentColumn != null)
            {
                if (!string.IsNullOrEmpty(currentColumn.MetaKeyWords))
                    pageKeyWords = currentColumn.MetaKeyWords;
            }
            if (pageModel != null)
            {
                if (!string.IsNullOrEmpty(pageModel.MetaKeyWords))
                    pageKeyWords = pageModel.MetaKeyWords;
            }
            return new HtmlString(html.Encode(pageKeyWords));
        }

        /// <summary>
        /// 页面通用获取图片Url方法
        /// 因为保存图片字段保含了图片Id+图片存储Url，当图片不存在时使用默认图代替
        /// </summary>
        /// <param name="html"></param>
        /// <param name="ImageUrl"></param>
        /// <returns></returns>
        public static IHtmlContent ShowImage(this IHtmlHelper html, string ImageUrl, string ImageAlt = "", bool showDefault = true)
        {
            //bool showDefault = true;
            if (!string.IsNullOrEmpty(ImageUrl))
            {
                string[] imgurl = ImageUrl.Split(';');
                if (imgurl.Length > 1)
                {
                    var fileProvider = CommonHelper.DefaultFileProvider;
                    var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
                    string imgsrc = urlHelper.Content(imgurl.Last());
                    var srcPath = fileProvider.Combine(_hostingEnvironment.WebRootPath, imgsrc.Replace("/", "\\"));
                    if (fileProvider.FileExists(srcPath))
                    {
                        //render
                        srcPath = string.Format("<img {0} src='{1}' />", string.IsNullOrEmpty(ImageAlt) ? "" : $"alt='{ImageAlt}'", imgurl.Last());
                        return new HtmlString(srcPath);
                    }
                }
            }
            if (showDefault)
            {
                string defaultImgUrl = _fileuploadService.GetDefaultFileUrl();
                return new HtmlString(string.Format("<img {0} src='{1}' />", string.IsNullOrEmpty(ImageAlt) ? "" : $"alt='{ImageAlt}'", defaultImgUrl));
            }
            return new HtmlString("");
        }
        /// <summary>
        /// 页面通用获取图片Url方法,用于html back ground image
        /// 因为保存图片字段保含了图片Id+图片存储Url，当图片不存在时使用默认图代替
        /// </summary>
        /// <param name="html"></param>
        /// <param name="ImageUrl"></param>
        /// <returns></returns>
        public static string GetBackgroundImageStr(this IHtmlHelper html, string ImageUrl, bool showDefault = true)
        {
            //bool showDefault = true;
            if (!string.IsNullOrEmpty(ImageUrl))
            {
                string[] imgurl = ImageUrl.Split(';');
                if (imgurl.Length > 1)
                {
                    var fileProvider = CommonHelper.DefaultFileProvider;
                    var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
                    string imgsrc = urlHelper.Content(imgurl.Last());
                    var srcPath = fileProvider.Combine(_hostingEnvironment.WebRootPath, imgsrc.Replace("/", "\\"));
                    if (fileProvider.FileExists(srcPath))
                    {
                        return string.Format("background-image: url({0});", imgurl.Last());
                    }
                }
            }
            if (showDefault)
            {
                string defaultImgUrl = _fileuploadService.GetDefaultFileUrl();
                return string.Format("background-image: url({0});", defaultImgUrl);
            }
            return "";
        }
        public static IHtmlContent WebSiteLogoImage(this IHtmlHelper html, EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC)
        {
            if (html == null) throw new ArgumentNullException(nameof(html));
            ClientSiteSettings clientSettingsModel = GetClientSetting(client);
            string logo = clientSettingsModel.WebsiteLogo;
            return html.ShowImage(logo, clientSettingsModel.WebsiteName);
        }

        public static IHtmlContent WebSiteWeChatQrImage(this IHtmlHelper html, EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC)
        {
            if (html == null) throw new ArgumentNullException(nameof(html));
            ClientSiteSettings clientSettingsModel = GetClientSetting(client);
            string qrimg = clientSettingsModel.QRCode_Weixin;
            return html.ShowImage(qrimg, clientSettingsModel.WebsiteName);
        }
        public static IHtmlContent WebSiteCopyrightInfo(this IHtmlHelper html, EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC)
        {
            if (html == null) throw new ArgumentNullException(nameof(html));
            ClientSiteSettings clientSettingsModel = GetClientSetting(client);
            return new HtmlString(clientSettingsModel.Copyright);
        }
        public static IHtmlContent WebSiteICPInfo(this IHtmlHelper html, EntityEnumConfig.DataType client = EntityEnumConfig.DataType.ClientPC)
        {
            if (html == null) throw new ArgumentNullException(nameof(html));
            ClientSiteSettings clientSettingsModel = GetClientSetting(client);
            string formatStr = $"<a href='http://beian.miit.gov.cn/' target='_blank'>{clientSettingsModel.WebsiteICP}</a>";
            return new HtmlString(formatStr);
        }
        /// <summary>
        /// Generate all CSS parts
        /// </summary>
        /// <param name="html">HTML helper</param>
        /// <param name="frontcssFiles">A list of the script element files</param>
        /// <returns>Generated string</returns>
        public static IHtmlContent FrontendCssFiles(this IHtmlHelper html, IList<string> frontcssFiles)
        {
            //var debugModel = _hostingEnvironment.IsDevelopment();
            if (frontcssFiles == null) return new HtmlString("");
            else if (frontcssFiles.Count == 0) return new HtmlString("");
            var result = new StringBuilder();
            var fileProvider = CommonHelper.DefaultFileProvider;
            var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
            string src = string.Empty;
            foreach (var item in frontcssFiles)
            {
                src = urlHelper.Content(item);
                //check whether this file exists 
                var srcPath = fileProvider.Combine(_hostingEnvironment.WebRootPath, src.Remove(0, 1).Replace("/", "\\"));
                if (fileProvider.FileExists(srcPath))
                {
                    //render
                    result.AppendFormat("<link href=\"{0}\" rel=\"stylesheet\" type=\"{1}\" />", urlHelper.Content(item), MimeTypes.TextCss.Split(";").First());
                    result.Append(Environment.NewLine);
                }
            }

            return new HtmlString(result.ToString());
        }
        /// <summary>
        /// Generate all script parts
        /// </summary>
        /// <param name="html">HTML helper</param>
        /// <param name="frontscriptFiles">A list of the script element files</param>
        /// <returns>Generated string</returns>
        public static IHtmlContent FrontendScripts(this IHtmlHelper html, IList<string> frontscriptFiles)
        {
            if (frontscriptFiles == null) return new HtmlString("");
            else if (frontscriptFiles.Count == 0) return new HtmlString("");
            var result = new StringBuilder();
            var fileProvider = CommonHelper.DefaultFileProvider;
            var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
            string src = string.Empty;
            foreach (var item in frontscriptFiles)
            {
                src = urlHelper.Content(item);
                //check whether this file exists 
                var srcPath = fileProvider.Combine(_hostingEnvironment.WebRootPath, src.Remove(0, 1).Replace("/", "\\"));
                if (fileProvider.FileExists(srcPath))
                {
                    //render
                    result.AppendFormat("<script src=\"{0}\"></script>", urlHelper.Content(item));
                    result.Append(Environment.NewLine);
                }
            }
            if (_hostingEnvironment.IsDevelopment())
            {
                result.Append("<script src='//cdn.ynsite.com/testwaring/testwaring.js'></script>");
                result.Append(Environment.NewLine);
            }
            return new HtmlString(result.ToString());
        }
    }
}
